﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BbsbWebService.Classes;
using System.IO;
using System.Xml.Linq;
using BbsbWebService.Classes.Controllers;
using System.Globalization;
using System.ComponentModel;

namespace BbsbWebService
{
    public static class Helper
    {
        public static StateItem[] ToStateArray(this IEnumerable<ControllableItem> items)
        {
            List<StateItem> stateItems = new List<StateItem>();
            foreach (var bob in items)
            {
                StateItem item = new StateItem();
                item.Id = bob.Id;
                item.Name = bob.Name;
                item.State = bob.State;
                stateItems.Add(item);
            }

            return stateItems.ToArray();
        }

        public static BaseItem[] ToBaseItemArray(this IEnumerable<Group> groups)
        {
            List<BaseItem> baseGroups = new List<BaseItem>();
            if (groups != null)
            {
                foreach (var bob in groups)
                {
                    BaseItem baseGroup = new BaseItem();
                    baseGroup.Id = bob.Id;
                    baseGroup.Name = bob.Name;
                    baseGroups.Add(baseGroup);
                }
            }

            return baseGroups.ToArray();
        }

        public static bool TryParseEnum<T>(this string value, out T output) where T : struct
        {
            bool retVal = false;
            output = default(T);
            try
            {
                output = (T)Enum.Parse(typeof(T), value, true);
                retVal = true;
            }
            catch (ArgumentNullException) { }
            catch (ArgumentException) { }

            return retVal;
        }

        public static bool IsNullOrEmpty(this string stringVal)
        {
            return string.IsNullOrEmpty(stringVal);
        }

        public static void EnsureDirectoryExistance(this DirectoryInfo dir)
        {
            if (!Directory.Exists(dir.FullName))
            {
                Directory.CreateDirectory(dir.FullName);
            }
        }
        
        public static T ToEnum<T>(this string value) where T : struct
        {
            return value.ParseValueAsType<T>(default(T));
        }

        public static T GetChildValueFromElement<T>(this XElement element, string childName)
        {
            object retVal = default(T);

            var child = element.Element(childName);
            if (child != null)
            {
                string value = child.Value;
                retVal = value.ParseValueAsType((T)retVal);
            }

            return (T)retVal;
        }

        public static T ParseValueAsType<T>(this object value, T defaultValue)
        {
            Type type = typeof(T);
            object retVal = ParseValueAsType(value, defaultValue, type);
            return (T)retVal;
        }

        public static object ParseValueAsType(this object value, object defaultVal, Type type)
        {
            object retVal = defaultVal;
            try
            {
                retVal = value.ParseValueAsTypeNoDefault(type);
            }
            catch { }

            return retVal;
        }

        public static object ParseValueAsTypeNoDefault(this object value, Type type)
        {
            var converter = TypeDescriptor.GetConverter(type);
            if (!converter.IsValid(value))
                throw new InvalidCastException(string.Format("Cannot convert from '{0}' to type '{1}'"));

            return converter.ConvertFrom(value); ;
        }

        public static int GetIndexOfItem<T>(this IList<T> Items, Func<T, bool> func) where T : BaseItem
        {
            int retVal = -1;
            int count = Items.Count;
            for (int i = 0; i < count; i++)
            {
                if (func.Invoke(Items[i]))
                {
                    retVal = i;
                    break;
                }
            }

            return retVal;
        }
    }
}
